import { getToken, removeToken } from '@g/utils/auth';
import Axios, { AxiosResponse } from "axios";
import router from '@/router'
import { ElMessage } from 'element-plus'

const baseURL = import.meta.env.VITE_APP_BASE_URL;

interface ResponseType<T = any> {
  code: string | number,
  data: T,
  msg: string | null,
  message: string | null
}

const axios = Axios.create({
  baseURL, // 基础 url
  timeout: 10000 // 超时 10s
});

const whiteList = ['login']
const reponseWhiteList = ['mng/test/uploadExcel'] // 响应白名单 无论返回的code是多少 都不拦截

// 请求拦截器
axios.interceptors.request.use(
  (config) => {
    // 判断是否在白名单
    if (!config.url || !whiteList.includes(config.url.split(baseURL)[0])) {
      if (!config.data) config.data = {}
      let token = getToken()
      // 判断token
      if (!token) {
        return Promise.reject('no_login')
      } else {
        // 如果登录了 headers 携带 token
        if (!config.headers) {
          config.headers = {}
        }
        config.headers.token = token ? token : ''
      }
    }
    // 其他配置信息...
    if (config.data && config.data.timeout) config.timeout = config.data.timeout
    return config
  },
  (error) => {
    Promise.reject(error)
  }
);

// 响应拦截器
axios.interceptors.response.use(
  (response: AxiosResponse<ResponseType>) => {
    const { data, status, config } = response
    // 判断请求状态
    if (status === 200) {
      const code = Number(data.code)
      // 判断code
      if (code === 200) {
        // 请求正常后的额外操作...
      } else {
        // 请求数据
        const requestData = typeof config.data === 'object' ? {} : JSON.parse(config.data)
        // 判断是否是白名单
        if (config.url && reponseWhiteList.includes(config.url)) {
          return data
        } else if (response.data instanceof Blob) {
          // 如果是下载文件 导出等 不进行处理
          return data
        } else {
          // 检查是否有不需要提示的数据信息 有的话不提示
          const notNeedMessage = requestData.notNeedMessage ? requestData.notNeedMessage : false
          if (!notNeedMessage) {
            ElMessage.error({ message: data.msg || data.message || 'Error', duration: 5 * 1000 })
          }
          // 403 登录过期
          if (code === 403) {
            removeToken()
            location.reload()
          }
        }
        // 其他响应校验...
        // 抛出错误
        return Promise.reject(data)
      }
    }
    return data
  },
  error => {
    if (error === 'no_login') {
      ElMessage.error({ message: '请登录！', duration: 5 * 1000 })
      router.push(`/login`)
    } else {
      ElMessage.error({ message: error ? (error.message ? error.message : error.msg) : '服务器错误', duration: 5 * 1000 })
      return Promise.reject(error)
    }
  }
);

export default axios;

